package com.youlai.boot.common.util;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.youlai.boot.weather.model.Location;

import java.nio.charset.StandardCharsets;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.security.*;

public class WeatherUtil {
    private final static String PUBLIC_KEY = "MCowBQYDK2VwAyEAd46os/YwTW/ZbjXpX1pwi+F+WRhIVveUjNVksFyVg98=";
    private final static String PRIVATE_KEY = "MC4CAQAwBQYDK2VwBCIEIGuY8JmhmTnDeFCNa0mpmryETryIiYepup8IQy3CIXW8";
    private final static String alg= "EdDSA";
    private final static String kid= "C9PRDCC32G";
    private final static String sub="3B899NBARJ";
    private static Long iat = 0L;
    private static Long exp = 0L;
    private final static String API_HOST="qq4ewquywp.re.qweatherapi.com";
    public static void main(String[] args) throws Exception {
        // API 地址
        String url = "https://"+API_HOST+"/geo/v2/city/lookup?location=kunming";

        // 发送 GET 请求
        HttpResponse response = HttpRequest.get(url)
                .header("Authorization", getWeatherToken()) // 添加 Authorization 头
                .timeout(5000) // 超时时间 5 秒
                .execute();

        // 获取返回结果
        String body = response.body();
        System.out.println("Response: " + body);
    }
    public static String getWeather(Location location)throws Exception{
        String weatherUrl = "https://"+API_HOST+"/v7/weather/now?location="+location.getLongitude()+","+location.getLatitude();
        String cityUrl="https://"+API_HOST+"/geo/v2/city/lookup?location="+location.getLongitude()+","+location.getLatitude();
        String weatherPerHourUrl = "https://"+API_HOST+"/v7/weather/24h?location="+location.getLongitude()+","+location.getLatitude();
        String weatherPerDayUrl = "https://"+API_HOST+"/v7/weather/3d?location="+location.getLongitude()+","+location.getLatitude();
        String airUrl = "https://"+API_HOST+"/airquality/v1/current/"+location.getLatitude()+"/"+location.getLongitude();

        // 发送 GET 请求
        HttpResponse weatherResponse = HttpRequest.get(weatherUrl)
                .header("Authorization", getWeatherToken()) // 添加 Authorization 头
                .timeout(5000) // 超时时间 5 秒
                .execute();
        HttpResponse cityResponse = HttpRequest.get(cityUrl)
                .header("Authorization", getWeatherToken()) // 添加 Authorization 头
                .timeout(5000) // 超时时间 5 秒
                .execute();
        HttpResponse hourResponse = HttpRequest.get(weatherPerHourUrl)
                .header("Authorization", getWeatherToken()) // 添加 Authorization 头
                .timeout(5000) // 超时时间 5 秒
                .execute();
        HttpResponse dayResponse = HttpRequest.get(weatherPerDayUrl)
                .header("Authorization", getWeatherToken()) // 添加 Authorization 头
                .timeout(5000) // 超时时间 5 秒
                .execute();
        HttpResponse airResponse = HttpRequest.get(airUrl)
                .header("Authorization", getWeatherToken()) // 添加 Authorization 头
                .timeout(5000) // 超时时间 5 秒
                .execute();

        // 获取返回结果
        String weatherBody = weatherResponse.body();
        String cityBody = cityResponse.body();
        String hourBody = hourResponse.body();
        String dayBody = dayResponse.body();
        String airBody = airResponse.body();
        JSONObject weatherObject = JSONUtil.parseObj(weatherBody);
        JSONObject cityObject = JSONUtil.parseObj(cityBody);
        JSONObject hourObject = JSONUtil.parseObj(hourBody);
        JSONObject dayObject = JSONUtil.parseObj(dayBody);
        JSONObject airObject = JSONUtil.parseObj(airBody);
        JSONObject res=new JSONObject();
        res.set("weather",weatherObject.get("now"));
        res.set("city",cityObject.getJSONArray("location").get(0));
        res.set("hour",hourObject.getJSONArray("hourly").subList(0,5));
        res.set("day",dayObject.getJSONArray("daily").get(0));

        Integer aqi = airObject.getJSONArray("indexes").getJSONObject(0).getInt("aqi");
        String level;
        if (aqi>0&&aqi<=50){
            level="优";
        }else if (aqi>51&&aqi<=100){
            level="良";
        }else if (aqi>101&&aqi<=150){
            level="轻度污染";
        }else if (aqi>151&&aqi<=200){
            level="中度污染";
        }else if (aqi>201&&aqi<=300){
            level="重度污染";
        }else {
            level="严重污染";
        }
        res.set("aqiLevel",level);

        return res.toString();
    }

    public static String getWeatherToken() throws Exception {
// 1️⃣ 生成 Header
        Map<String, Object> header = new HashMap<>();
        header.put("alg", alg);
        header.put("kid", kid);

        String headerJson = new ObjectMapper().writeValueAsString(header);
        String headerBase64 = base64UrlEncode(headerJson);

        // 2️⃣ 生成 Payload
        iat=(System.currentTimeMillis() / 1000) - 30;
        exp=iat + 86400;
        Map<String, Object> payload = new HashMap<>();
        payload.put("sub", sub);
        payload.put("iat", iat);
        payload.put("exp", exp);

        String payloadJson = new ObjectMapper().writeValueAsString(payload);
        String payloadBase64 = base64UrlEncode(payloadJson);

        // 3️⃣ 生成 Signature
        String dataToSign = headerBase64 + "." + payloadBase64;
        String signatureBase64 = signWithEd25519(dataToSign, PRIVATE_KEY);

        // 4️⃣ 组合 JWT Token
        return "Bearer "+dataToSign + "." + signatureBase64;
    }

    // Base64URL 编码（去掉 "="，替换 "+" 和 "/"）
    private static String base64UrlEncode(String data) {
        return Base64.getUrlEncoder().withoutPadding().encodeToString(data.getBytes(StandardCharsets.UTF_8));
    }

    // Ed25519 签名
    private static String signWithEd25519(String data, String privateKeyB64) throws Exception {
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyB64);
        KeyFactory keyFactory = KeyFactory.getInstance("Ed25519");
        PrivateKey privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));

        Signature signature = Signature.getInstance("Ed25519");
        signature.initSign(privateKey);
        signature.update(data.getBytes(StandardCharsets.UTF_8));
        byte[] signedBytes = signature.sign();

        return Base64.getUrlEncoder().withoutPadding().encodeToString(signedBytes);
    }
}
